//============================================================================
// Name        : UrlResolver.cpp
// Author      : Brendon Beebe
// Version     :
// Description : Url Resolver for CS240
//============================================================================

#include <iostream>
#include <stdio.h>
#include <cstring>
#include <stdlib.h>
#include "UrlResolver.h"
using namespace std;

const int MAX = 1024;
char baseUrl[MAX], relUrl[MAX];
char scheme[MAX]="";
char net_loc[MAX]="";
char path[MAX]="/";
char query[MAX]="";
char fragment[MAX]="";


int main(int argc,char *argv[]) {
	if(parseArguments(argc,argv)==-1)
		exit(1);
	parseAbsoluteUrl(baseUrl);
	parseRelativeUrl();
}

int parseRelativeUrl(){
	char newUrl[MAX]="";
	//strcpy(newUrl, baseUrl);

	if(*relUrl=='#'){
		strcpy(newUrl,scheme);
		strcat(newUrl,"://");
		strcat(newUrl,net_loc);
		strcat(newUrl,path);
		strcat(newUrl,query);
		strcat(newUrl,relUrl);
	} else if (*relUrl=='/' ){
		strcpy(newUrl,scheme);
		strcat(newUrl,"://");
		strcat(newUrl,net_loc);
		strcat(newUrl,relUrl);
	} else{
		strcpy(newUrl,baseUrl);
		if(*(path+1)!='\0')
			upOneDir(newUrl);
		char * tokenizedUrl = strtok(relUrl,"/");
		while (tokenizedUrl != NULL){

			if(strncmp(tokenizedUrl,"..",2)==0)
				upOneDir(newUrl);
			else if(strncmp(tokenizedUrl,".",1)==0)
				printf("");
			else{
				strcat(newUrl,"/");
				strcat(newUrl,tokenizedUrl);
			}
			tokenizedUrl = strtok(NULL,"/");
		}

	}
	printf("%s\n",newUrl);
}
int upOneDir(char * url){
	char* p = url;
	p = strrchr(url,'/');
	*p = '\0';
	return 0;
}
const char* getWorkingDirectory(char * url){
	const char* p = url;
	return strchr(p,'/');
}
//An absolute URL is split accordingly:
//<scheme>://<net_loc>/<path>?<query>#<fragment
//<scheme> = includes ://
//<net_lo> = is empty on a file scheme
//
int parseAbsoluteUrl(char * baseUrl){
	int offset=0;
	offset = parseScheme(0,baseUrl);
	offset = parseNetLoc(offset,baseUrl);
	offset = parsePath(offset,baseUrl);
	offset = parseQuery(offset,baseUrl);
	offset = parseFragment(offset,baseUrl);
	//printf("%s\n%s\n%s\n%s\n%s\n",scheme,net_loc,path,query,fragment);
}

int parseFragment(int offset, char * url){
	const char * p = url+ offset;
	if(*p != '#' )
		return offset;
	p++;
	offset++;
	while (*p != '\0')
		p++;

	strncat(fragment,url+offset,(p - url)-offset);
	return (p - url);
}
int parseQuery(int offset, char * url){
	const char * p = url+ offset;
	if(*p != '?' ) return offset;
	p++;

	while ( *p != '#' && *p != '\0')
		p++;

	strncat(query,url+offset,(p - url)-offset);
	return (p - url);
}
int parseScheme(int offset,char * url){
	const char * p = url+ offset;
	while ( *p != '/' && *p != '\0')
		p++;
	strncat(scheme,url+(offset),((p-1) - url)-offset);
	if(*(p+1) == '/' && *p == '/' )
		p+=2;
	else
		return -1;
	return (p - url);
}
int parsePath(int offset, char * url){
	const char * p = url+ offset;
	while ( *p != '?' && *p != '\0' && *p != '#')
		p++;
	strncat(path,url+offset,(p - url)-offset);
	return (p - url);
}
int parseNetLoc(int offset, char * url){
	const char * p = url+ offset;
	while ( *p != '/' && *p != '\0' && *p != '?' && *p != '#')
		p++;

	strncat(net_loc,url+offset,(p - url)-offset);
	if(*p == '/' )
		p++;
	return (p - url);
}


int parseArguments(int argc, char *argv[] ){
	// There should be 2 arguments, the absolute and relativeurl
	if(argc != 3 ) {
		printf("Usage: ./UrlResolver AbsoluteUrl RelativeUrl\n");
		return(-1);
	}
	strcpy(baseUrl, argv[1]);
	strcpy(relUrl, argv[2]);
	return 0;
}
